﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DNA.Mvc.Exporting;
using System.IO;
using System.Web.Security;

namespace DNA.Mvc.Controllers
{
    public class ThemeController : Controller
    {
        private WebSiteContext _context;

        public ThemeController(WebSiteContext context) { _context = context; }

        [Authorize]
        public ActionResult UIDesigner(string name, string basePath = "backgrounds")
        {
            ViewBag.IdPrefix = "d" + Guid.NewGuid().ToString().Substring(0, 5);
            ViewBag.Element = name;
            ViewBag.BgPath = Url.Content("~/webshared/home/images/" + basePath);
            return PartialView();
        }

        [Authorize]
        public ActionResult Preview()
        {
            return View();
        }

        [Authorize]
        [SecurityAction("Theming", "Change web site theme", "Allows users can change the theme of current website.",
            TitleResName = "SA_ChangeTheme",
            DescResName = "SA_ChangeThemeDesc",
            PermssionSetResName = "SA_Theming")]
        [MyControlPanel(ResKey = "RES_THEME_SETTINGS", Order = 1, ShowInPersonalSiteOnly = true, Group = "Appearance", GroupResKey = "RES_APPEARANCE_SETTINGS")]
        [SiteControlPanel(ResKey = "RES_THEME_SETTINGS", Order = 1, Group = "Appearance", GroupResKey = "RES_APPEARANCE_SETTINGS")]
        public ActionResult List()
        {
            return View(_context.DataContext.Themes.All());
        }

        [Authorize]
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult List(string theme)
        {
            if (string.IsNullOrEmpty(theme)) throw new ArgumentNullException("theme");
            var web = _context.Web;
            web.Theme = theme;
            _context.DataContext.Webs.Update(web);
            _context.DataContext.SaveChanges();
            return View(_context.DataContext.Themes.All());
        }

        [Authorize]
        [SecurityAction("Theming", "Download themes", "Allows users can download the theme package.",
            TitleResName = "SA_DownloadTheme",
            DescResName = "SA_DownloadThemeDesc",
            PermssionSetResName = "SA_Theming")]
        public FileResult Download(string name)
        {
            var pkg = _context.DataContext.Themes.Find(t => t.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
            var images = new List<string>();
            if (pkg.Images.Count > 0)
            {
                foreach (var img in pkg.Images)
                {
                    var _path = pkg.ResolvePhysicalPath();
                    var _imgFullPath = _path.EndsWith("\\") ? (_path + img.Url) : (_path + "\\" + img.Url);
                    if (System.IO.File.Exists(_imgFullPath))
                        images.Add(_imgFullPath);
                }
            }

            var tmp = WebSiteContext.GetTemporaryDirectory(HttpContext);
            var src = Server.MapPath("~/content/themes/" + name);
            if (!Directory.Exists(tmp)) Directory.CreateDirectory(tmp);
            FileUtility.CopyDirectory(src, tmp+"\\content\\content\\themes\\"+name);
            
            var stream = new MemoryStream();
            var zip = new DNA.IO.Compress.ZipCompress(stream, tmp);
            zip.AddPath(tmp);
            zip.AddFile(src + "\\install.xml", "install.xml");
            zip.AddFile(src + "\\manifest.xml", "manifest.xml");

            foreach (var img in images)
                zip.AddFile(img, img.ToLower().Replace(src.ToLower() + "\\", ""));

            zip.Compress();
            stream.Position = 0;

            return File(stream, "application/x-zip-compressed", name + ".zip");
        }

        [Authorize]
        [SecurityAction("Theming", "Create theme", "Allows users can create new themes.",
            TitleResName = "SA_CreateTheme",
            DescResName = "SA_CreateThemeDesc",
            PermssionSetResName = "SA_Theming")]
        public ActionResult SaveAs()
        {
            return View();
        }

        [Authorize, HttpPost]
        public ActionResult SaveAs(Package package, bool replaceIfExists)
        {
            if (!replaceIfExists)
            {
                if (_context.DataContext.Solutions.Find(s => s.Name.Equals(package.Name, StringComparison.OrdinalIgnoreCase)) != null)
                {
                    ViewData.ModelState.AddModelError("", string.Format("There is a theme named \"{0}\" exists.", package.Name));
                    return View(package);
                }
            }

            if (ModelState.IsValid)
            {
                var tmpPath = WebSiteContext.GetTemporaryDirectory(HttpContext);
                if (!Directory.Exists(tmpPath))
                    Directory.CreateDirectory(tmpPath);

                if (Request.Files.Count > 0)
                {
                    for (int i = 0; i < Request.Files.Count; i++)
                    {
                        var file = Request.Files[i];
                        if ((file.ContentLength > 0) && (!string.IsNullOrEmpty(file.FileName)))
                        {
                            var srvFileName = tmpPath + Path.GetFileName(file.FileName);
                            file.SaveAs(srvFileName);
                            package.Images.Add(new ImageRes() { Url = srvFileName });
                        }
                    }
                }

                var exporters = new List<Exporter>();
                var themePath = HttpContext.Server.MapPath("~/Content/Themes/" + package.Name + "/");

                exporters.Add(new DNA.Mvc.Exporting.Exporters.PackageExporter()
                {
                    MatchKey = "Package"
                });

                exporters.Add(new DNA.Mvc.Exporting.Exporters.FilesExporter()
                {
                    MatchKey = "ThemePath",
                    Destination = themePath
                });

                var container = new ExporterContainer(exporters);
                package.Authors = new List<Contact>();

                if (string.IsNullOrEmpty(package.Title))
                    package.Title = package.Name;

                var user = Membership.GetUser(User.Identity.Name);
                var userUri = "";

                if (HttpContext.Profile["WebSite"] != null && !string.IsNullOrEmpty(HttpContext.Profile["WebSite"].ToString()))
                    userUri = HttpContext.Profile["WebSite"].ToString();

                var author = new Contact()
                {
                    Name = user.GetDisplayName(),
                    Email = user.Email,
                    WebSite = userUri
                };

                package.Authors.Add(author);

                var _params = new
                {
                    Package = package,
                    ThemePath = "~/content/themes/" + _context.Web.Theme + "/"
                };

                if (!Directory.Exists(themePath))
                    Directory.CreateDirectory(themePath);

                container.Process(themePath, _params, HttpContext);

                Directory.Delete(tmpPath);
                return RedirectToAction("List", new { Area = "", website = _context.Web.Name });
            }

            return View(package);
        }


        [SiteControlPanel(ResKey = "RES_STYLE_DESIGNER", Order = 3, Group = "Appearance", GroupResKey = "RES_APPEARANCE_SETTINGS")]
        [SecurityAction("Theming", "Design themes", "Allows users can use the style designer to design themes.",
            TitleResName = "SA_DesignTheme",
            DescResName = "SA_DesignThemeDesc",
            PermssionSetResName = "SA_Theming")]
        public ActionResult Design()
        {
            return View();
        }

        [Authorize]
        [HttpPost]
        public ActionResult Design(FormCollection forms, int saveOption)
        {
            var web = _context.Web;
            string themedir = HttpContext.Server.MapPath("~/Content/Themes/" + web.Theme);
            string cssText = forms["Web.CssText"];

            switch (saveOption)
            {
                case 1: //append to default
                    var dnacssfilename = themedir + "\\dna.ui.css";
                    if (System.IO.File.Exists(dnacssfilename) && !string.IsNullOrEmpty(cssText))
                    {
                        using (var writer = new System.IO.StreamWriter(dnacssfilename))
                        {
                            writer.Write(cssText);
                        }
                    }
                    web.CssText = "";
                    break;
                case 2: //overwrite default
                    var defaultfilename = themedir + "\\dna.ui.css";

                    if (System.IO.File.Exists(defaultfilename))
                        System.IO.File.Delete(defaultfilename);

                    if (!string.IsNullOrEmpty(cssText))
                    {
                        using (var writer = System.IO.File.CreateText(defaultfilename))
                        {
                            writer.Write(cssText);
                            writer.Flush();
                        }
                        web.CssText = "";
                    }
                    break;
                case 3: //save new
                    var newCssFilename = themedir + "\\screen.css";

                    if (System.IO.File.Exists(newCssFilename))
                        System.IO.File.Delete(newCssFilename);

                    if (!string.IsNullOrEmpty(cssText))
                    {
                        using (var writer = System.IO.File.CreateText(newCssFilename))
                        {
                            writer.Write(cssText);
                            writer.Flush();
                        }
                        web.CssText = "";
                    }
                    break;
                default:
                    web.CssText = cssText;
                    break;
            }
            _context.DataContext.Webs.Update(web);
            _context.DataContext.SaveChanges();
            return View(web);
        }
    }
}
